/*
 * Mixer_test.cpp
 *
 *  Created on: 3 lis 2013
 *      Author: dawid.wysakowicz
 */

#include "Mixer.hpp"
#include "gtest_wrapper.hpp"
#include <algorithm>

namespace mixer
{

TEST(Mixer, twoAllelsDifferent)
{
	dna::marker locus;
	for (char i = 'A'; i <= 'B'; ++i)
	{
		locus.push_back(dna::allel(i));
	}

	Mixer mix;
	std::list<dna::genotypeSet> variants = mix.combineGenotypes(
			locus);

	ASSERT_EQ(1, variants.size())<< "wrong variants count!";
	std::stringstream str;
	std::for_each(variants.front().begin(), variants.front().end(),
			[&str](const dna::genotype& gen)
			{
				str << gen;
			});

	EXPECT_STREQ("(A,B)", str.str().c_str()) << "Bad genotypes: " << str.str();
}

TEST(Mixer, fourAllelsDifferent)
{
	dna::marker locus;
	for (char i = 'A'; i <= 'D'; ++i)
	{
		locus.push_back(dna::allel(i));
	}


	Mixer mix;
	std::list<dna::genotypeSet> variants = mix.combineGenotypes(
			locus);

	ASSERT_EQ(6, variants.size())<< "wrong variants count!";
	const char* results[] =
	{ "(A,B)(C,D)", "(A,C)(B,D)", "(A,D)(B,C)", "(B,C)(A,D)", "(B,D)(A,C)", "(C,D)(A,B)" };
	size_t i = 0;
	std::for_each(variants.begin(), variants.end(),
			[&i, &results] (const dna::genotypeSet& collection)
			{

				std::stringstream str;
				std::for_each(collection.begin(), collection.end(),
						[&str](const dna::genotype& gen)
						{
							str << gen;
						});
				EXPECT_STREQ(results[i++], str.str().c_str()) << "Bad results: " << str.str() << "at position: "<<i - 1;
			});

}

TEST(Mixer, fourSame)
{
	dna::marker locus;
	locus.push_back(dna::allel('A'));
	locus.push_back(dna::allel('A'));
	locus.push_back(dna::allel('A'));
	locus.push_back(dna::allel('A'));

	Mixer mix;
	std::list<dna::genotypeSet> variants = mix.combineGenotypes(
			locus);

	ASSERT_EQ(1, variants.size())<< "wrong variants count!";
	const char* results[] = { "(A,A)(A,A)"};
	size_t i = 0;
	std::for_each(variants.begin(), variants.end(),
			[&i, &results] (const dna::genotypeSet& collection)
			{

				std::stringstream str;
				std::for_each(collection.begin(), collection.end(),
						[&str](const dna::genotype& gen)
						{
							str << gen;
						});
				EXPECT_STREQ(results[i++], str.str().c_str()) << "Bad results: " << str.str()<< "at position: "<<i;
			});

}

TEST(Mixer, fourWithTwoSame)
{
	dna::marker locus;
	locus.push_back(dna::allel('A'));
	locus.push_back(dna::allel('A'));
	locus.push_back(dna::allel('B'));
	locus.push_back(dna::allel('C'));

	Mixer mix;
	std::list<dna::genotypeSet> variants = mix.combineGenotypes(
			locus);

	ASSERT_EQ(4, variants.size())<< "wrong variants count!";
	const char* results[] = { "(A,A)(B,C)", "(A,B)(A,C)", "(A,C)(A,B)", "(B,C)(A,A)"};
	size_t i = 0;
	std::for_each(variants.begin(), variants.end(),
			[&i, &results] (const dna::genotypeSet& collection)
			{

				std::stringstream str;
				std::for_each(collection.begin(), collection.end(),
						[&str](const dna::genotype& gen)
						{
							str << gen;
						});
				EXPECT_STREQ(results[i++], str.str().c_str()) << "Bad results: " << str.str()<< "at position: "<<i;
			});

}

TEST(Mixer, fourWithThreeSame)
{
	dna::marker locus;
	locus.push_back(dna::allel('A'));
	locus.push_back(dna::allel('A'));
	locus.push_back(dna::allel('A'));
	locus.push_back(dna::allel('B'));

	Mixer mix;
	std::list<dna::genotypeSet> variants = mix.combineGenotypes(
			locus);

	ASSERT_EQ(2, variants.size())<< "wrong variants count!";
	const char* results[] = { "(A,A)(A,B)", "(A,B)(A,A)"};
	size_t i = 0;
	std::for_each(variants.begin(), variants.end(),
			[&i, &results] (const dna::genotypeSet& collection)
			{

				std::stringstream str;
				std::for_each(collection.begin(), collection.end(),
						[&str](const dna::genotype& gen)
						{
							str << gen;
						});
				EXPECT_STREQ(results[i++], str.str().c_str()) << "Bad results: " << str.str()<< "at position: "<<i;
			});

}

TEST(Mixer, DISABLED_trying)
{
	dna::marker locus;
//	locus.push_back(dna::allel(1, 'A'));
//	locus.push_back(dna::allel(1, 'A'));
//		locus.push_back(dna::allel(1, 'A'));
	locus.push_back(dna::allel('A'));
	for (char i = 'A'; i <= 'C'; ++i)
	{
		locus.push_back(dna::allel(i));
	}


	Mixer mix;
	std::list<dna::genotypeSet> variants = mix.combineGenotypes(
			locus);

	size_t i = 0;
	std::for_each(variants.begin(), variants.end(),
			[&i] (const dna::genotypeSet& collection)
			{

				std::stringstream str;
				std::for_each(collection.begin(), collection.end(),
						[&str](const dna::genotype& gen)
						{
							str << gen;
						});
				std::cout << i++ << " " << str.str() << std::endl;
			});

}


TEST(Mixer, emptyAllels)
{
	dna::marker locus;

	Mixer mix;
	std::list<dna::genotypeSet> variants = mix.combineGenotypes(
			locus);

	ASSERT_EQ(0, variants.size())<< "wrong variants count!";
}
} /* namespace mixer */
